package com.xdy.server.core2;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

/**
 * @Author: XDY.
 * @Email: 2280944114@qq.com
 * @CreateTime: 2023-03-13  15:58
 * @Description: web服务器
 * @Version: 1.0
 */
public class DyServer {

    //服务监听端口
    private int port;

    //选择器
    private Selector selector;

    //服务通道
    private ServerSocketChannel serverSocketChannel;

    //服务是否运行
    private boolean isRunning;

    public DyServer() {
        this(8888);
    }

    public DyServer(int port) {
        this.port = port;
    }

    /**
     * 启动服务
     */
    public void start() {
        try {
            //初始化配置
            WebApp.init();
            //初始化服务
            initServer();
            //接收请求
            receive();
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("服务器出错啦~...");
        }
    }

    /**
     * 初始化服务
     */
    private void initServer() throws IOException {
        //获取通道
        serverSocketChannel = ServerSocketChannel.open();
        //绑定服务端口
        serverSocketChannel.bind(new InetSocketAddress(8888));
        //必须设置成非阻塞通道
        serverSocketChannel.configureBlocking(false);
        //获取Selector
        selector = Selector.open();
        //注册channel,并指定感兴趣的事件(可以接收请求)
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        //服务设置为启动
        isRunning = true;
        System.out.println("服务启动成功，监听端口：" + port);
    }

    /**
     * 接收请求
     */
    public void receive() throws IOException {
        //选择器轮询
        while (isRunning){
            //阻塞等待就绪通道
            selector.select();
            //获取就绪选择器键集合
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            //获取迭代器
            Iterator<SelectionKey> iterator = selectionKeys.iterator();
            while (iterator.hasNext()){
                //获取key
                SelectionKey key = iterator.next();
                //进行通道操作判断处理业务
                if (key.isAcceptable()){
                    SocketChannel socketChannel = serverSocketChannel.accept();
                    socketChannel.configureBlocking(false);
                    socketChannel.register(selector,SelectionKey.OP_READ);
                }else if (key.isReadable()){
                    SocketChannel channel = (SocketChannel) key.channel();
                    channel.configureBlocking(false);
                    //创建分发器
                    new Dispatcher(channel).dispatch();
                }
                iterator.remove();
            }
        }
    }

    /**
     * 停止服务
     */
    public void stop() {
        isRunning = false;
        try {
            serverSocketChannel.close();
            System.out.println("服务器已停止...");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        DyServer server = new DyServer();
        server.start();
    }
}
